// -*-c++-*- osgNVPR - Copyright (C) 2012 osgNVPR Development Team
// $Id$

#ifndef OSGNVPR_EXTENSIONS
#define OSGNVPR_EXTENSIONS

#include <osg/GL>
#include <osg/RenderInfo>
#include <osg/Referenced>
#include <osgNVPR/Export>

#define GL_CLOSE_PATH_NV                         0x00
#define GL_MOVE_TO_NV                            0x02
#define GL_RELATIVE_MOVE_TO_NV                   0x03
#define GL_LINE_TO_NV                            0x04
#define GL_RELATIVE_LINE_TO_NV                   0x05
#define GL_HORIZONTAL_LINE_TO_NV                 0x06
#define GL_RELATIVE_HORIZONTAL_LINE_TO_NV        0x07
#define GL_VERTICAL_LINE_TO_NV                   0x08
#define GL_RELATIVE_VERTICAL_LINE_TO_NV          0x09
#define GL_QUADRATIC_CURVE_TO_NV                 0x0A
#define GL_RELATIVE_QUADRATIC_CURVE_TO_NV        0x0B
#define GL_CUBIC_CURVE_TO_NV                     0x0C
#define GL_RELATIVE_CUBIC_CURVE_TO_NV            0x0D
#define GL_SMOOTH_QUADRATIC_CURVE_TO_NV          0x0E
#define GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F
#define GL_SMOOTH_CUBIC_CURVE_TO_NV              0x10
#define GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV     0x11
#define GL_SMALL_CCW_ARC_TO_NV                   0x12
#define GL_RELATIVE_SMALL_CCW_ARC_TO_NV          0x13
#define GL_SMALL_CW_ARC_TO_NV                    0x14
#define GL_RELATIVE_SMALL_CW_ARC_TO_NV           0x15
#define GL_LARGE_CCW_ARC_TO_NV                   0x16
#define GL_RELATIVE_LARGE_CCW_ARC_TO_NV          0x17
#define GL_LARGE_CW_ARC_TO_NV                    0x18
#define GL_RELATIVE_LARGE_CW_ARC_TO_NV           0x19
#define GL_CIRCULAR_CCW_ARC_TO_NV                0xF8
#define GL_CIRCULAR_CW_ARC_TO_NV                 0xFA
#define GL_CIRCULAR_TANGENT_ARC_TO_NV            0xFC
#define GL_ARC_TO_NV                             0xFE
#define GL_RELATIVE_ARC_TO_NV                    0xFF

#define GL_PATH_FORMAT_SVG_NV                0x9070
#define GL_PATH_FORMAT_PS_NV                 0x9071
#define GL_STANDARD_FONT_NAME_NV             0x9072
#define GL_SYSTEM_FONT_NAME_NV               0x9073
#define GL_FILE_NAME_NV                      0x9074
#define GL_PATH_STROKE_WIDTH_NV              0x9075
#define GL_PATH_END_CAPS_NV                  0x9076
#define GL_PATH_INITIAL_END_CAP_NV           0x9077
#define GL_PATH_TERMINAL_END_CAP_NV          0x9078
#define GL_PATH_JOIN_STYLE_NV                0x9079
#define GL_PATH_MITER_LIMIT_NV               0x907A
#define GL_PATH_DASH_CAPS_NV                 0x907B
#define GL_PATH_INITIAL_DASH_CAP_NV          0x907C
#define GL_PATH_TERMINAL_DASH_CAP_NV         0x907D
#define GL_PATH_DASH_OFFSET_NV               0x907E
#define GL_PATH_CLIENT_LENGTH_NV             0x907F
#define GL_PATH_FILL_MODE_NV                 0x9080
#define GL_PATH_FILL_MASK_NV                 0x9081
#define GL_PATH_FILL_COVER_MODE_NV           0x9082
#define GL_PATH_STROKE_COVER_MODE_NV         0x9083
#define GL_PATH_STROKE_MASK_NV               0x9084
#define GL_PATH_SAMPLE_QUALITY_NV            0x9085
#define GL_COUNT_UP_NV                       0x9088
#define GL_COUNT_DOWN_NV                     0x9089
#define GL_PATH_OBJECT_BOUNDING_BOX_NV       0x908A
#define GL_CONVEX_HULL_NV                    0x908B
#define GL_BOUNDING_BOX_NV                   0x908D
#define GL_TRANSLATE_X_NV                    0x908E
#define GL_TRANSLATE_Y_NV                    0x908F
#define GL_TRANSLATE_2D_NV                   0x9090
#define GL_TRANSLATE_3D_NV                   0x9091
#define GL_AFFINE_2D_NV                      0x9092
#define GL_AFFINE_3D_NV                      0x9094
#define GL_TRANSPOSE_AFFINE_2D_NV            0x9096
#define GL_TRANSPOSE_AFFINE_3D_NV            0x9098
#define GL_UTF8_NV                           0x909A
#define GL_UTF16_NV                          0x909B
#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C
#define GL_PATH_COMMAND_COUNT_NV             0x909D
#define GL_PATH_COORD_COUNT_NV               0x909E
#define GL_PATH_DASH_ARRAY_COUNT_NV          0x909F
#define GL_PATH_COMPUTED_LENGTH_NV           0x90A0
#define GL_PATH_FILL_BOUNDING_BOX_NV         0x90A1
#define GL_PATH_STROKE_BOUNDING_BOX_NV       0x90A2
#define GL_SQUARE_NV                         0x90A3
#define GL_ROUND_NV                          0x90A4
#define GL_TRIANGULAR_NV                     0x90A5
#define GL_BEVEL_NV                          0x90A6
#define GL_MITER_REVERT_NV                   0x90A7
#define GL_MITER_TRUNCATE_NV                 0x90A8
#define GL_SKIP_MISSING_GLYPH_NV             0x90A9
#define GL_USE_MISSING_GLYPH_NV              0x90AA
#define GL_PATH_DASH_OFFSET_RESET_NV         0x90B4
#define GL_MOVE_TO_RESETS_NV                 0x90B5
#define GL_MOVE_TO_CONTINUES_NV              0x90B6

#define GL_BOLD_BIT_NV   0x01
#define GL_ITALIC_BIT_NV 0x02

#define GL_PATH_ERROR_POSITION_NV 0x90AB
#define GL_PATH_FOG_GEN_MODE_NV   0x90AC

#define GL_GLYPH_WIDTH_BIT_NV                      0x01
#define GL_GLYPH_HEIGHT_BIT_NV                     0x02
#define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV       0x04
#define GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV       0x08
#define GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10
#define GL_GLYPH_VERTICAL_BEARING_X_BIT_NV         0x20
#define GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV         0x40
#define GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV   0x80
#define GL_GLYPH_HAS_KERNING_NV                    0x100

#define GL_FONT_X_MIN_BOUNDS_NV        0x00010000
#define GL_FONT_Y_MIN_BOUNDS_NV        0x00020000
#define GL_FONT_X_MAX_BOUNDS_NV        0x00040000
#define GL_FONT_Y_MAX_BOUNDS_NV        0x00080000
#define GL_FONT_UNITS_PER_EM_NV        0x00100000
#define GL_FONT_ASCENDER_NV            0x00200000
#define GL_FONT_DESCENDER_NV           0x00400000
#define GL_FONT_HEIGHT_NV              0x00800000
#define GL_FONT_MAX_ADVANCE_WIDTH_NV   0x01000000
#define GL_FONT_MAX_ADVANCE_HEIGHT_NV  0x02000000
#define GL_FONT_UNDERLINE_POSITION_NV  0x04000000
#define GL_FONT_UNDERLINE_THICKNESS_NV 0x08000000
#define GL_FONT_HAS_KERNING_NV         0x10000000

#define GL_ACCUM_ADJACENT_PAIRS_NV             0x90AD
#define GL_ADJACENT_PAIRS_NV                   0x90AE
#define GL_FIRST_TO_REST_NV                    0x90AF
#define GL_PATH_GEN_MODE_NV                    0x90B0
#define GL_PATH_GEN_COEFF_NV                   0x90B1
#define GL_PATH_GEN_COLOR_FORMAT_NV            0x90B2
#define GL_PATH_GEN_COMPONENTS_NV              0x90B3
#define GL_PATH_STENCIL_FUNC_NV                0x90B7
#define GL_PATH_STENCIL_REF_NV                 0x90B8
#define GL_PATH_STENCIL_VALUE_MASK_NV          0x90B9
#define GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD
#define GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV  0x90BE
#define GL_PATH_COVER_DEPTH_FUNC_NV            0x90BF

namespace osgNVPR {

class OSGNVPR_EXPORT Extensions: public osg::Referenced {
public:
	typedef GLuint    GL_APIENTRY glGenPathsNVProc                   (GLsizei range);
	typedef void      GL_APIENTRY glDeletePathsNVProc                (GLuint path, GLsizei range);
	typedef GLboolean GL_APIENTRY glIsPathNVProc                     (GLuint path);
	typedef void      GL_APIENTRY glPathCommandsNVProc               (GLuint path, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const GLvoid *coords);
	typedef void      GL_APIENTRY glPathCoordsNVProc                 (GLuint path, GLsizei numCoords, GLenum coordType, const GLvoid *coords);
	typedef void      GL_APIENTRY glPathSubCommandsNVProc            (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const GLvoid *coords);
	typedef void      GL_APIENTRY glPathSubCoordsNVProc              (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const GLvoid *coords);
	typedef void      GL_APIENTRY glPathStringNVProc                 (GLuint path, GLenum format, GLsizei length, const GLvoid *pathString);
	typedef void      GL_APIENTRY glPathGlyphsNVProc                 (GLuint firstPathName, GLenum fontTarget, const GLvoid *fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const GLvoid *charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
	typedef void      GL_APIENTRY glPathGlyphRangeNVProc             (GLuint firstPathName, GLenum fontTarget, const GLvoid *fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
	typedef void      GL_APIENTRY glWeightPathsNVProc                (GLuint resultPath, GLsizei numPaths, const GLuint *paths, const GLfloat *weights);
	typedef void      GL_APIENTRY glCopyPathNVProc                   (GLuint resultPath, GLuint srcPath);
	typedef void      GL_APIENTRY glInterpolatePathsNVProc           (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight);
	typedef void      GL_APIENTRY glTransformPathNVProc              (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat *transformValues);
	typedef void      GL_APIENTRY glPathParameterivNVProc            (GLuint path, GLenum pname, const GLint *value);
	typedef void      GL_APIENTRY glPathParameteriNVProc             (GLuint path, GLenum pname, GLint value);
	typedef void      GL_APIENTRY glPathParameterfvNVProc            (GLuint path, GLenum pname, const GLfloat *value);
	typedef void      GL_APIENTRY glPathParameterfNVProc             (GLuint path, GLenum pname, GLfloat value);
	typedef void      GL_APIENTRY glPathDashArrayNVProc              (GLuint path, GLsizei dashCount, const GLfloat *dashArray);
	typedef void      GL_APIENTRY glPathStencilFuncNVProc            (GLenum func, GLint ref, GLuint mask);
	typedef void      GL_APIENTRY glPathStencilDepthOffsetNVProc     (GLfloat factor, GLfloat units);
	typedef void      GL_APIENTRY glStencilFillPathNVProc            (GLuint path, GLenum fillMode, GLuint mask);
	typedef void      GL_APIENTRY glStencilStrokePathNVProc          (GLuint path, GLint reference, GLuint mask);
	typedef void      GL_APIENTRY glStencilFillPathInstancedNVProc   (GLsizei numPaths, GLenum pathNameType, const GLvoid *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues);
	typedef void      GL_APIENTRY glStencilStrokePathInstancedNVProc (GLsizei numPaths, GLenum pathNameType, const GLvoid *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues);
	typedef void      GL_APIENTRY glPathCoverDepthFuncNVProc         (GLenum func);
	typedef void      GL_APIENTRY glPathColorGenNVProc               (GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat *coeffs);
	typedef void      GL_APIENTRY glPathTexGenNVProc                 (GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat *coeffs);
	typedef void      GL_APIENTRY glPathFogGenNVProc                 (GLenum genMode);
	typedef void      GL_APIENTRY glCoverFillPathNVProc              (GLuint path, GLenum coverMode);
	typedef void      GL_APIENTRY glCoverStrokePathNVProc            (GLuint path, GLenum coverMode);
	typedef void      GL_APIENTRY glCoverFillPathInstancedNVProc     (GLsizei numPaths, GLenum pathNameType, const GLvoid *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
	typedef void      GL_APIENTRY glCoverStrokePathInstancedNVProc   (GLsizei numPaths, GLenum pathNameType, const GLvoid *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
	typedef void      GL_APIENTRY glGetPathParameterivNVProc         (GLuint path, GLenum pname, GLint *value);
	typedef void      GL_APIENTRY glGetPathParameterfvNVProc         (GLuint path, GLenum pname, GLfloat *value);
	typedef void      GL_APIENTRY glGetPathCommandsNVProc            (GLuint path, GLubyte *commands);
	typedef void      GL_APIENTRY glGetPathCoordsNVProc              (GLuint path, GLfloat *coords);
	typedef void      GL_APIENTRY glGetPathDashArrayNVProc           (GLuint path, GLfloat *dashArray);
	typedef void      GL_APIENTRY glGetPathMetricsNVProc             (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const GLvoid *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics);
	typedef void      GL_APIENTRY glGetPathMetricRangeNVProc         (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat *metrics);
	typedef void      GL_APIENTRY glGetPathSpacingNVProc             (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const GLvoid *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing);
	typedef void      GL_APIENTRY glGetPathColorGenivNVProc          (GLenum color, GLenum pname, GLint *value);
	typedef void      GL_APIENTRY glGetPathColorGenfvNVProc          (GLenum color, GLenum pname, GLfloat *value);
	typedef void      GL_APIENTRY glGetPathTexGenivNVProc            (GLenum texCoordSet, GLenum pname, GLint *value);
	typedef void      GL_APIENTRY glGetPathTexGenfvNVProc            (GLenum texCoordSet, GLenum pname, GLfloat *value);
	typedef GLboolean GL_APIENTRY glIsPointInFillPathNVProc          (GLuint path, GLuint mask, GLfloat x, GLfloat y);
	typedef GLboolean GL_APIENTRY glIsPointInStrokePathNVProc        (GLuint path, GLfloat x, GLfloat y);
	typedef GLfloat   GL_APIENTRY glGetPathLengthNVProc              (GLuint path, GLsizei startSegment, GLsizei numSegments);
	typedef GLboolean GL_APIENTRY glPointAlongPathNVProc             (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY);

	glGenPathsNVProc*                   glGenPathsNV;
	glDeletePathsNVProc*                glDeletePathsNV;
	glIsPathNVProc*                     glIsPathNV;
	glPathCommandsNVProc*               glPathCommandsNV;
	glPathCoordsNVProc*                 glPathCoordsNV;
	glPathSubCommandsNVProc*            glPathSubCommandsNV;
	glPathSubCoordsNVProc*              glPathSubCoordsNV;
	glPathStringNVProc*                 glPathStringNV;
	glPathGlyphsNVProc*                 glPathGlyphsNV;
	glPathGlyphRangeNVProc*             glPathGlyphRangeNV;
	glWeightPathsNVProc*                glWeightPathsNV;
	glCopyPathNVProc*                   glCopyPathNV;
	glInterpolatePathsNVProc*           glInterpolatePathsNV;
	glTransformPathNVProc*              glTransformPathNV;
	glPathParameterivNVProc*            glPathParameterivNV;
	glPathParameteriNVProc*             glPathParameteriNV;
	glPathParameterfvNVProc*            glPathParameterfvNV;
	glPathParameterfNVProc*             glPathParameterfNV;
	glPathDashArrayNVProc*              glPathDashArrayNV;
	glPathStencilFuncNVProc*            glPathStencilFuncNV;
	glPathStencilDepthOffsetNVProc*     glPathStencilDepthOffsetNV;
	glStencilFillPathNVProc*            glStencilFillPathNV;
	glStencilStrokePathNVProc*          glStencilStrokePathNV;
	glStencilFillPathInstancedNVProc*   glStencilFillPathInstancedNV;
	glStencilStrokePathInstancedNVProc* glStencilStrokePathInstancedNV;
	glPathCoverDepthFuncNVProc*         glPathCoverDepthFuncNV;
	glPathColorGenNVProc*               glPathColorGenNV;
	glPathTexGenNVProc*                 glPathTexGenNV;
	glPathFogGenNVProc*                 glPathFogGenNV;
	glCoverFillPathNVProc*              glCoverFillPathNV;
	glCoverStrokePathNVProc*            glCoverStrokePathNV;
	glCoverFillPathInstancedNVProc*     glCoverFillPathInstancedNV;
	glCoverStrokePathInstancedNVProc*   glCoverStrokePathInstancedNV;
	glGetPathParameterivNVProc*         glGetPathParameterivNV;
	glGetPathParameterfvNVProc*         glGetPathParameterfvNV;
	glGetPathCommandsNVProc*            glGetPathCommandsNV;
	glGetPathCoordsNVProc*              glGetPathCoordsNV;
	glGetPathDashArrayNVProc*           glGetPathDashArrayNV;
	glGetPathMetricsNVProc*             glGetPathMetricsNV;
	glGetPathMetricRangeNVProc*         glGetPathMetricRangeNV;
	glGetPathSpacingNVProc*             glGetPathSpacingNV;
	glGetPathColorGenivNVProc*          glGetPathColorGenivNV;
	glGetPathColorGenfvNVProc*          glGetPathColorGenfvNV;
	glGetPathTexGenivNVProc*            glGetPathTexGenivNV;
	glGetPathTexGenfvNVProc*            glGetPathTexGenfvNV;
	glIsPointInFillPathNVProc*          glIsPointInFillPathNV;
	glIsPointInStrokePathNVProc*        glIsPointInStrokePathNV;
	glGetPathLengthNVProc*              glGetPathLengthNV;
	glPointAlongPathNVProc*             glPointAlongPathNV;

	static Extensions* instance(unsigned contextID);

	bool isSupported() const { return _supported; }

protected:
	Extensions(unsigned int contextID);

	bool initialize(unsigned int contextID);

	bool _supported;
};

// Helper utility to get an Extensions pointer (or null). It will also print out useful
// warning text if the extension isn't supported.
OSGNVPR_EXPORT Extensions* getNVPRExtensions(unsigned int contextID);

OSGNVPR_EXPORT inline Extensions* getNVPRExtensions(const osg::State* state) {
	return getNVPRExtensions(state->getContextID());
}

OSGNVPR_EXPORT inline Extensions* getNVPRExtensions(const osg::RenderInfo& renderInfo) {
	return getNVPRExtensions(renderInfo.getState()->getContextID());
}

}

#endif

